package com.qf.java2201.edu.userservice.handler;

import com.qf.java2201.common.R;
import com.qf.java2201.edu.userservice.filter.TokenFilter;
import com.qf.java2201.edu.userservice.token.TokenService;
import com.qf.java2201.edu.userservice.utils.ResponseUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.logout.LogoutSuccessHandler;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @date 2022/6/5
 * @desc
 */
@Configuration
public class SecurityHandlerConfig {

    @Autowired
    private TokenService tokenService;


    /**
     * 登陆成功，返回Token
     * @return
     */
    @Bean
    public AuthenticationSuccessHandler loginSuccessHandler() {
        return new AuthenticationSuccessHandler() {

            @Override
            public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
                                                Authentication authentication) throws IOException, ServletException {
                response.setContentType("application/json;charset=UTF-8");
                ServletOutputStream outputStream = response.getOutputStream();
                R ok = R.ok();
                ResponseUtil.responseJson(response, HttpStatus.OK.value(), ok);
            }
        };
    }

    /**
     * 登陆失败
     *登录失败处理类
     * @return
     */
    @Bean
    public AuthenticationFailureHandler loginFailureHandler() {
        return new AuthenticationFailureHandler() {

            @Override
            public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
                                                AuthenticationException exception) throws IOException, ServletException {
                String msg = null;
                if (exception instanceof BadCredentialsException) {
                    msg = "密码错误";
                } else {
                    msg = exception.getMessage();
                }
                R error = R.error();
                error.setCode(HttpStatus.UNAUTHORIZED.value());
                error.setMessage(msg);
                ResponseUtil.responseJson(response, HttpStatus.UNAUTHORIZED.value(), error);
            }
        };

    }

    /**
     * 未登录，返回401
     *
     * @return
     */
    @Bean
    public AuthenticationEntryPoint authenticationEntryPoint() {
        return new AuthenticationEntryPoint() {
            @Override
            public void commence(HttpServletRequest request, HttpServletResponse response,
                                 AuthenticationException authException) throws IOException, ServletException {

                R error = R.error();
                error.setCode(HttpStatus.UNAUTHORIZED.value());
                error.setMessage("请先登录");

                ResponseUtil.responseJson(response, HttpStatus.UNAUTHORIZED.value(), error);
            }
        };
    }

    /**
     * 退出处理
     *
     * @return
     */
    @Bean
    public LogoutSuccessHandler logoutSuccessHandler() {
        return new LogoutSuccessHandler() {

            @Override
            public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response,
                                        Authentication authentication) throws IOException, ServletException {
                R ok = R.ok();
                ok.setCode(HttpStatus.OK.value());
                ok.setMessage("退出成功");


                String token = TokenFilter.getToken(request);
                tokenService.deleteToken(token);

                ResponseUtil.responseJson(response, HttpStatus.OK.value(), ok);
            }
        };

    }

    //权限不足处理类
    @Bean
    public AccessDeniedHandler accessDeniedHandler(){
        return new AccessDeniedHandler() {
            @Override
            public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
                R error = R.error();
                error.setCode(HttpStatus.FORBIDDEN.value());
                error.setMessage(accessDeniedException.getMessage());

                ResponseUtil.responseJson(response, HttpStatus.FORBIDDEN.value(), error);
            }
        };
    }

}
